home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 July
/
Macworld (1999-07).dmg
/
Shareware World
/
Info
/
For Developers
/
Mops 3.4.sea
/
Mops source
/
SpeechStuff folder
/
SpeechMgr
< prev
next >
Wrap
Text File
|
1993-08-21
|
13KB
|
755 lines
\ Speech Manager support code and classes.
\
\ The Speech Manager is not currently in ROM. To utilize this class, you
\ will have to obtain the Macintosh Speech Manager from an appropriate
\ source. (sources I know of: ftp via ftp.apple.com, develop CD)
\
need Gestalt
: gestaltSpeechAttr 'type ttsc ;
0 constant gestaltSpeechMgrPresent
: kTextToSpeechSynthType 'type ttsc ;
: kTextToSpeechVoiceType 'type ttvd ;
: kTextToSpeechVoiceFileType 'type ttvf ;
: kTextToSpeechVoiceBundleType 'type ttvb ;
\ Speech Manager error codes
-240 constant noSynthFound
-241 constant synthOpenFailed
-242 constant synthNotReady
-243 constant bufTooSmall
-244 constant voiceNotFound
-245 constant incompatibleVoice
-246 constant badDictFormat
-247 constant badPhonemeText
\ constants for SpeakBuffer and text done callback
1 constant kNoEndingProsody
2 constant kNoSpeechInterrupt
4 constant kPreFlightThenPause
\ constants for StopSpeechAt and PauseSpeechAt
0 constant kImmediate
1 constant kEndOfWord
2 constant kEndOfSentence
\ GetSpeechInfo and SetSpeechInfo selectors
: soStatus 'type stat ;
: soErrors 'type erro ;
: soInputMode 'type inpt ;
: soCharacterMode 'type char ;
: soNumberMode 'type nmbr ;
: soRate 'type rate ;
: soPitchBase 'type pbas ;
: soPitchMod 'type pmod ;
: soVolume 'type volm ;
: soSynthType 'type vers ;
: soRecentSync 'type sync ;
: soPhonemeSymbols 'type phsy ;
: soCurrentVoice 'type cvox ;
: soCommandDelimiter 'type dlim ;
: soReset 'type rset ;
: soCurrentA5 'type myA5 ;
: soRefCon 'type refc ;
: soTextDoneCallBack 'type tdcb ;
: soSpeechDoneCallBack 'type sdcb ;
: soSyncCallBack 'type sycb ;
: soErrorCallBack 'type ercb ;
: soPhonemeCallBack 'type phcb ;
: soWordCallBack 'type wdcb ;
: soSynthExtension 'type xtnd ;
\ Speaking mode constants
: modeText 'type TEXT ;
: modeTX 'type TX ;
: modePhonemes 'type PHON ;
: modePH 'type PH ;
: modeNormal 'type NORM ;
: modeLiteral 'type LTRL ;
\ GetVoiceInfo selectors
: soVoiceDescription 'type info ;
: soVoiceFile 'type fref ;
\ Gender constants
0 constant kNeuter
1 constant kMale
2 constant kFemale
0 value NumOfVoices
345 constant DescriptionLength
:CLASS SpeechChannel super{ object }
longword data
:m get:
get: data
;m
;CLASS
:CLASS VoiceSpec super{ object }
var creator
var id
:m Creator?: ( -- creator )
get: creator
;m
:m id?: ( -- id )
get: id
;m
\ Note that Apple recommends against setting these value directly in order
\ to maintain forward compatibility. Therefore, there are no methods for
\ manually placing these. Note that if you do include them, you are risking
\ NOT having compatibility with future versions of the Speech Manager.
;CLASS
:CLASS VoiceDescription super{ object }
var Length
VoiceSpec voice
var version
64 bytes name
256 bytes comment
int gender
int age
int script
int language
int region
16 bytes reserved
:m Length?: ( -- length )
get: Length
;m
:m VoiceSpec?: ( -- creator id )
creator?: voice
id?: voice
;m
:m Name?: ( -- ^name ) \ Note: 64 bytes!
addr: name
;m
:m Comment?: ( -- ^str255 ) \ Pass the pointer to this
addr: comment
;m
:m Gender?: ( -- w ) \ 0 neutral 1 male 2 female
get: gender
;m
:m Age?: ( -- w )
get: age
;m
:m Script?: ( -- w )
get: script
;m
:m Language?: ( -- w )
get: language
;m
:m Region?: ( -- w )
get: region
;m
;CLASS
:CLASS VoiceFileInfo super{ object }
\ FSSpec type taken from class file.
object FSSpec \ Use as a placeholder
int FSvRefNum
var FSDirID
64 bytes FileName
int resID
:m ^FSSpec?: ( -- ^FSSpec )
addr: FSSpec
;m
:m VolumeID?: ( -- n )
get: FSvRefNum
;m
:m DirID?: ( -- n )
get: FSDirID
;m
:m ^Filename?: ( -- ^fname )
addr: FileName
;m
:m ResourceID#?: ( -- n )
get: resID
;m
;CLASS
:CLASS SpeechStatusInfo super{ object }
1 bytes outputBusy
1 bytes outputPaused
4 bytes inputBytesLeft
2 bytes phonemeCode
:m Busy?: ( -- n )
addr: outputBusy c@x
;m
:m Paused?: ( -- n )
addr: outputPaused c@x
;m
:m BytesLeft?: ( -- n )
addr: inputBytesLeft @
;m
:m Code?: ( -- n )
addr: phonemeCode w@x
;m
;CLASS
:CLASS SpeechErrorInfo super{ object }
int count
int oldest
var oldPos
int newest
var newPos
:m count?: ( -- n )
get: count
;m
:m oldest?: ( -- n )
get: oldest
;m
:m oldPosition?: ( -- n )
get: oldPos
;m
:m newest?: ( -- n )
get: newest
;m
:m newPosition?: ( -- n )
get: newPos
;m
;CLASS
:CLASS SpeechVersionInfo super{ object }
var synthType
var synthSubType
var synthManufacturer
var synthFlags
7 bytes synthVersion
:m type?: ( -- n )
get: synthType
;m
:m subType?: ( -- n )
get: synthSubType
;m
:m Manufacturer?: ( -- n )
get: synthManufacturer
;m
:m Flags?: ( -- n )
get: synthFlags
;m
\ Note: all of the above have been converted from their assembly 4 bytes
\ to vars. The feeling is that any decoding that might have to be done on
\ such things can be done by the parent program.
:m ^version?: ( -- ^version )
addr: synthVersion
;m
;CLASS
:CLASS PhonemeInfo super{ object }
int opcode
16 bytes phStr
32 bytes exampleStr
int hiliteStart
int hiliteEnd
:m opcode?: ( -- n )
get: opcode
;m
:m ^String: ( -- ^string )
addr: phStr
;m
:m ^example: ( -- ^exampleString )
addr: exampleStr
;m
:m Start?: ( -- n )
get: hiliteStart
;m
:m End?: ( -- n )
get: hiliteEnd
;m
;CLASS
:CLASS PhonemeDescriptor super{ object }
int phonemeCount
phonemeInfo thePhonemes
:m HowMany?: ( -- n )
get: phonemeCount
;m
:m ^thesePhonemes: ( -- ^phonemeInfo )
addr: thePhonemes
;m
;CLASS
:CLASS SpeechXtndData super{ object }
var synthCreator
int synthData
:m Creator?: ( -- n )
get: synthCreator
;m
:m Data?: ( -- n )
get: synthData
;m
:m putCreator: ( n -- )
put: synthCreator
;m
:m putData: ( n -- )
put: synthData
;m
;CLASS
:CLASS DelimiterInfo super{ object } \ defaults to "[[" and "]]"
2 bytes startDelimiter
2 bytes endDelimiter
:m setStart: ( c1 c2 -- )
addr: startDelimiter dup 1+ rot swap c! c!
;m
:m setEnd: ( c1 c2 -- )
addr: endDelimiter dup 1+ swap c! c!
;m
;CLASS
\ OSErr - word
\ OSType - var
: SpeechManagerVersion
word0
call SpeechManagerVersion
i->l
;
: IsMySpeechBusy? ( -- n )
word0
call SpeechBusy
i->l
;
: IsAnySpeechBusy? ( -- n )
word0
call SpeechBusySystemWide
i->l
;
\ : Voices? ( -- rc ) \ Number of available voices
\ 0 -> NumOfVoices
\ word0
\ ['] NumOfVoices
\ call CountVoices
\ i->l
\ ;
:CLASS Talker super{ object }
string myString
string phonemebuf
var phonemeBufLength
voiceSpec voice
voiceDescription voiceInfo
handleList channels
Objhandle myInfo
handlelist myInfoList
handleList tempList
longword temp
int voiceCount
:m new:
release: channels
release: myInfoList
;m
:m put: ( addr len -- )
put: myString
;m
:m get: ( addr len -- )
get: myString
;m
:m SayIt: ( -- rc )
word0 \ Save room for rc
get: MyString str255
call SpeakString
i->l
;m
:m SetVoice: { creator id -- rc }
word0
creator makeint
id makeint
addr: voice \ get the pointer
call MakeVoiceSpec
i->l
;m
:m Voices: ( -- rc voices )
word0
addr: voiceCount
call CountVoices
i->l
get: voiceCount
;m
:m GetAVoice: { index -- rc }
index makeint \ Will leave room for return code
addr: voice
call GetIndVoice
i->l
;m
:m GetVoiceDescription: ( -- rc )
word0
addr: voice
addr: voiceInfo
DescriptionLength
call GetVoiceDescription
i->l
;m
:m NewChannel: ( -- rc )
word0
addr: voice
['] SpeechChannel newObj: channels
obj: channels
call NewSpeechChannel
i->l
;m
:m DisposeChannel: { channel -- rc }
word0
channel select: channels
obj: channels get: **
call DisposeSpeechChannel
i->l
channel select: channels removeObj: channels
;m
:m SpeakToChannel: { channel -- rc }
word0
channel select: channels
obj: channels get: **
get: myString
call SpeakText
i->l
;m
:m Halt: { channel -- rc }
word0
channel select: channels
obj: channels get: **
call StopSpeech
i->l
;m
:m SetRate: { channel whole fraction -- rc }
word0
channel select: channels
obj: channels get: **
whole fraction pack
call setSpeechRate
i->l
;m
:m GetRate: { channel -- rc whole fraction }
word0
channel select: channels
obj: channels get: **
addr: temp
call getSpeechRate
i->l
get: temp
unpack
;m
:m SetPitch: { channel whole fraction -- rc }
word0
channel select: channels
obj: channels get: **
whole fraction pack
call setSpeechPitch
i->l
;m
:m GetPitch: { channel -- rc whole fraction }
word0
channel select: channels
obj: channels get: **
addr: temp
call getSpeechPitch
i->l
get: temp
unpack
;m
:m Stop: { channel whereToStop -- rc } \ 0 = now, 1 eow, 2 eos
word0
channel select: channels
obj: channels get: **
whereToStop
call StopSpeechAt
i->l
;m
:m Pause: { channel whereToPause -- rc } \ 0 now, 1 eow, 2 eos
word0
channel select: channels
obj: channels get: **
whereToPause
call PauseSpeechAt
i->l
;m
:m Continue: { channel -- rc }
word0
channel select: channels
obj: channels get: **
call ContinueSpeech
i->l
;m
:m SpeakWithOptions: { channel flags -- rc }
word0
channel select: channels
obj: channels get: **
get: myString
flags
call SpeakBuffer
i->l
;m
:m TextToPhonemes: { channel -- rc }
clear: phonemeBuf
32000 dup put: phonemeBufLength setSize: phonemeBuf
word0
channel select: channels
obj: channels get: **
get: myString
handle: phonemeBuf addr: phonemeBufLength
call TextToPhonemes
i->l
get: phonemeBufLength
setsize: phonemeBuf
;m
:m getPhonemes: ( -- addr len )
get: phonemeBuf
;m
:m GetInfo: { channel selector -- rc ^obj }
releaseObj: myInfo
selector
case
soStatus of
['] SpeechStatusInfo newObj: myInfo
endof
soErrors of
['] SpeechErrorInfo newObj: myInfo
endof
soInputMode of
['] var newObj: myInfo
endof
soCharacterMode of
['] var newObj: myInfo
endof
soNumberMode of
['] var newObj: myInfo
endof
soRate of
['] var newObj: myInfo
endof
soPitchBase of
['] var newObj: myInfo
endof
soPitchMod of
['] var newObj: myInfo
endof
soVolume of
['] var newObj: myInfo
endof
soSynthType of
['] SpeechVersionInfo newObj: myInfo
endof
soRecentSync of
['] var newObj: myInfo
endof
soPhonemeSymbols of
['] phonemeDescriptor newObj: myInfo
endof
soSynthExtension of
['] SpeechXtndData newObj: myInfo
endof
." Big trouble... no match"
endcase
word0
channel select: channels
obj: channels get: **
selector
obj: myInfo
call GetSpeechInfo
i->l
obj: myInfo
;m
private
:m CallSetInfo: { channel selector -- rc }
word0
channel select: channels
obj: channels get: **
selector
obj: myInfo
call SetSpeechInfo
i->l
;m
:m SetUpSpeechInfoObject: { channel selector -- }
clear: myInfo
selector
case
soInputMode of
['] var newObj: myInfo
endof
soCharacterMode of
['] var newObj: myInfo
endof
soNumberMode of
['] var newObj: myInfo
endof
soRate of
['] var newObj: myInfo
endof
soPitchBase of
['] var newObj: myInfo
endof
soPitchMod of
['] var newObj: myInfo
endof
soVolume of
['] var newObj: myInfo
endof
soCurrentVoice of
['] VoiceSpec newObj: myInfo
endof
soCommandDelimiter of
['] DelimiterInfo newObj: myInfo
endof
soReset of
['] var newObj: myInfo
endof
soCurrentA5 of
['] var newObj: myInfo
endof
soRefCon of
['] var newObj: myInfo
endof
soTextDoneCallBack of
['] var newObj: myInfo
endof
soSpeechDoneCallBack of
['] var newObj: myInfo
endof
soSyncCallBack of
['] var newObj: myInfo
endof
soErrorCallBack of
['] var newObj: myInfo
endof
soPhonemeCallBack of
['] var newObj: myInfo
endof
soWordCallBack of
['] var newObj: myInfo
endof
soSynthExtension of
['] SpeechXtndData newObj: myInfo
endof
." Big trouble... no match"
endcase
;m
public
:m SetInfo: { channel selector -- rc }
channel selector setupSpeechInfoObject: self
channel selector callSetInfo: self
;m
:m Dictionary: { channel dichandle -- }
word0
channel select: channels
obj: channels get: **
dichandle
call UseDictionary
i->l
;m
:m VoiceInfo: { selector -- rc ^obj }
selector soVoiceDescription =
if
['] VoiceDescription newObj: myInfo
else
selector soVoiceFile =
if
['] VoiceFileInfo newObj: myInfo
else
." No Match" exit
then
then
addr: voice
selector
obj: myInfo
call GetVoiceInfo
i->l
obj: myInfo
;m
;CLASS